#!/usr/bin/env python3
"""
dblatex MCP Server

面向 dblatex 软件的 MCP 服务器，提供将 DocBook XML 文档转换为 LaTeX 及相关格式的命令行工具封装。

MCP tools 列表：
1. dblatex_basic_commands - 测试基本帮助、版本、输出文件和后端引擎选项
2. dblatex_config_options - 测试配置文件、调试诊断和索引样式选项
3. dblatex_format_options - 测试图形格式、输入格式和路径相关选项
4. dblatex_processing_options - 测试书目路径、XSLT 处理、参数设置和安静模式选项
5. dblatex_output_options - 测试 TeX 后处理、样式文件、输出格式和文档样式选项
6. dblatex_advanced_options - 测试临时目录、详细输出、XSLT 选项和高级处理选项

所有工具返回统一的 JSON 结构：
{
    "success": bool,
    "command": str,
    "exit_code": int,
    "stdout": str,
    "stderr": str
}
"""

import subprocess
import json
from typing import List, Optional
from mcp.server.fastmcp import FastMCP, Context

mcp = FastMCP("dblatex MCP Server")

@mcp.tool()
def dblatex_basic_commands(
    xml_file: str,
    output_file: Optional[str] = None,
    output_dir: Optional[str] = None,
    backend: Optional[str] = None,
    show_help: bool = False,
    show_version: bool = False
) -> dict:
    """
    测试 dblatex 基本命令选项
    
    参数:
        xml_file: 输入的 XML 文件路径
        output_file: 输出文件路径（-o/--output）
        output_dir: 输出目录路径（-O/--output-dir）
        backend: 后端引擎类型：pdftex/dvips/xetex（-b/--backend）
        show_help: 是否显示帮助信息（-h/--help）
        show_version: 是否显示版本信息（-v/--version）
    
    返回:
        统一 JSON 结构包含命令执行结果
    """
    cmd = ["dblatex"]
    
    if show_help:
        cmd.extend(["-h"])
    elif show_version:
        cmd.extend(["-v"])
    else:
        if output_file:
            cmd.extend(["-o", output_file])
        elif output_dir:
            cmd.extend(["-O", output_dir])
            cmd.extend(["-P", "set.book.num=all", "-P", "use.id.as.filename=1"])
        
        if backend:
            cmd.extend(["-b", backend])
        
        cmd.append(xml_file)
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def dblatex_config_options(
    xml_file: str,
    output_file: str,
    config_file: Optional[str] = None,
    change_dir: Optional[str] = None,
    debug: bool = False,
    dump: bool = False,
    index_style: Optional[str] = None
) -> dict:
    """
    测试 dblatex 配置和调试选项
    
    参数:
        xml_file: 输入的 XML 文件路径
        output_file: 输出文件路径
        config_file: 配置文件路径（-c/-S/--config）
        change_dir: 改变工作目录（-C/--changedir）
        debug: 启用调试模式（-d/--debug）
        dump: 启用堆栈转储（-D/--dump）
        index_style: 索引样式文件路径（-e/--indexstyle）
    
    返回:
        统一 JSON 结构包含命令执行结果
    """
    cmd = ["dblatex", "-o", output_file]
    
    if config_file:
        cmd.extend(["-c", config_file])
    
    if change_dir:
        cmd.extend(["-C", change_dir])
    
    if debug:
        cmd.append("-d")
    
    if dump:
        cmd.append("-D")
    
    if index_style:
        cmd.extend(["-e", index_style])
    
    cmd.append(xml_file)
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def dblatex_format_options(
    xml_file: str,
    output_file: str,
    fig_format: Optional[str] = None,
    input_format: Optional[str] = None,
    tex_inputs: Optional[str] = None,
    fig_paths: Optional[List[str]] = None,
    bst_path: Optional[str] = None
) -> dict:
    """
    测试 dblatex 格式和路径选项
    
    参数:
        xml_file: 输入的 XML 文件路径
        output_file: 输出文件路径
        fig_format: 图形格式：eps/fig/pdf（-f/--fig-format）
        input_format: 输入格式（-F/--input-format）
        tex_inputs: TeX 输入路径（-i/--texinputs）
        fig_paths: 图形文件搜索路径列表（-I/--fig-path）
        bst_path: BST 文件路径（-l/--bst-path）
    
    返回:
        统一 JSON 结构包含命令执行结果
    """
    cmd = ["dblatex", "-o", output_file]
    
    if fig_format:
        cmd.extend(["-f", fig_format])
    
    if input_format:
        cmd.extend(["-F", input_format])
    
    if tex_inputs:
        cmd.extend(["-i", tex_inputs])
    
    if fig_paths:
        for path in fig_paths:
            cmd.extend(["-I", path])
    
    if bst_path:
        cmd.extend(["-l", bst_path])
    
    cmd.append(xml_file)
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def dblatex_processing_options(
    xml_file: str,
    output_file: str,
    bib_path: Optional[str] = None,
    xslt_engine: Optional[str] = None,
    xsl_user: Optional[str] = None,
    param: Optional[str] = None,
    quiet: bool = False
) -> dict:
    """
    测试 dblatex 处理选项
    
    参数:
        xml_file: 输入的 XML 文件路径
        output_file: 输出文件路径
        bib_path: 书目文件路径（-L/--bib-path）
        xslt_engine: XSLT 引擎（-m/--xslt）
        xsl_user: 用户 XSL 文件路径（-p/--xsl-user）
        param: 参数设置（-P/--param）
        quiet: 启用安静模式（-q/--quiet）
    
    返回:
        统一 JSON 结构包含命令执行结果
    """
    cmd = ["dblatex", "-o", output_file]
    
    if bib_path:
        cmd.extend(["-L", bib_path])
    
    if xslt_engine:
        cmd.extend(["-m", xslt_engine])
    
    if xsl_user:
        cmd.extend(["-p", xsl_user])
    
    if param:
        cmd.extend(["-P", param])
    
    if quiet:
        cmd.append("-q")
    
    cmd.append(xml_file)
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def dblatex_output_options(
    xml_file: str,
    output_file: str,
    tex_post: Optional[str] = None,
    tex_style: Optional[str] = None,
    output_type: Optional[str] = None,
    document_style: Optional[str] = None
) -> dict:
    """
    测试 dblatex 输出选项
    
    参数:
        xml_file: 输入的 XML 文件路径
        output_file: 输出文件路径
        tex_post: TeX 后处理脚本（-r/--texpost）
        tex_style: TeX 样式文件（-s/--texstyle）
        output_type: 输出格式：tex/dvi/ps/pdf（-t/--type）
        document_style: 文档样式：db2latex/native/simple（-T/--style）
    
    返回:
        统一 JSON 结构包含命令执行结果
    """
    cmd = ["dblatex", "-o", output_file]
    
    if tex_post:
        cmd.extend(["-r", tex_post])
    
    if tex_style:
        cmd.extend(["-s", tex_style])
    
    if output_type:
        cmd.extend(["-t", output_type])
    
    if document_style:
        cmd.extend(["-T", document_style])
    
    cmd.append(xml_file)
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def dblatex_advanced_options(
    xml_file: str,
    output_file: str,
    tmp_dir: Optional[str] = None,
    verbose: bool = False,
    xslt_opts: Optional[str] = None,
    no_external: bool = False,
    no_batch: bool = False
) -> dict:
    """
    测试 dblatex 高级选项
    
    参数:
        xml_file: 输入的 XML 文件路径
        output_file: 输出文件路径
        tmp_dir: 临时目录路径（--tmpdir）
        verbose: 启用详细输出（-V/--verbose）
        xslt_opts: XSLT 选项（-x/--xslt-opts）
        no_external: 禁用外部引用（-X/--no-external）
        no_batch: 禁用批处理模式（-B/--no-batch）
    
    返回:
        统一 JSON 结构包含命令执行结果
    """
    cmd = ["dblatex", "-o", output_file]
    
    if tmp_dir:
        cmd.extend(["--tmpdir", tmp_dir])
    
    if verbose:
        cmd.append("-V")
    
    if xslt_opts:
        cmd.extend(["-x", xslt_opts])
    
    if no_external:
        cmd.append("-X")
    
    if no_batch:
        cmd.append("-B")
    
    cmd.append(xml_file)
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            "success": result.returncode == 0,
            "command": " ".join(cmd),
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": " ".join(cmd),
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

if __name__ == "__main__":
    mcp.run()